//
//  SimpleNetwork.swift
//  SimpleNetwork
//
//  Created by 谭淇 on 15/3/4.
//  Copyright (c) 2015年 谭淇. All rights reserved.
//

import Foundation

public enum HTTPMethod: String {
    case GET = "GET"
    case POST = "POST"
}

// 定义闭包类型（类型别名 - 别名首字母一定要大写）
typealias Completion = (result: AnyObject?, error: NSError?) -> ()

public class SimpleNetwork {
    
    ///  请求JSON
    ///
    ///  :param: method     请求方法
    ///  :param: urlSString 请求url字符串
    ///  :param: params     请求参数
    ///  :param: completion 完成回调
    public func requestJSON(method: HTTPMethod, _ urlString: String, _ params: [String: String]?, completion: ((result: AnyObject?, error: NSError?) -> ())) {
        // 实例化网络请求
        if let req = request(method, urlString, params) {
            // 网络请求成功
            session?.dataTaskWithRequest(req, completionHandler: { (data, _, error) -> Void in
                // 如果有错误，直接回调
                if error != nil {
                    completion(result: nil, error: error)
                    return
                }
                // 反序列化
                let json: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: nil)
                // 判断是否反序列化成功
                if json != nil {
                    // 成功 - 在主线程成功回调 
                    dispatch_async(dispatch_get_main_queue(), { () -> Void in
                        completion(result: json, error: nil)
                    })
                } else {
                    // 失败
                    let err = NSError(domain: SimpleNetwork.errorDomain, code: -1, userInfo: ["error": "反序列化失败"])
                    completion(result: nil, error: err)
                }
            }).resume()
        } else {
            // 网络请求没有成功
            /// domain - 错误所属领域字符串 com.simpleNetwork.error
            /// code - 如果是复杂的系统，可以是自己定义的错误码
            /// userInfo - 错误信息字典
            let err = NSError(domain: SimpleNetwork.errorDomain, code: -1, userInfo: ["error": "请求建立失败"])
            completion(result: nil, error: err)
        }
    }
    
    // (static)类属性，跟对象无关！
    private static let errorDomain = "com.simpleNetwork.error"
    
    ///  返回网络访问的请求
    ///
    ///  :param: method     请求方法
    ///  :param: urlSString 请求url字符串
    ///  :param: params     请求参数
    ///
    ///  :returns: 可为nil的网络请求
    func request(method: HTTPMethod, _ urlString: String, _ params: [String: String]?) -> NSURLRequest? {
        // 1.isEmpty 是 ""和nil的合并
        if urlString.isEmpty {
            return nil
        }
        
        var request: NSMutableURLRequest?
        var urlStr: String = urlString
        
        // 2.GET方法：URL的参数是拼接在URL字符串中的
        if method == .GET {
            if let query = queryString(params) {
                urlStr += "?\(query)"
            }
            request = NSMutableURLRequest(URL: NSURL(string: urlStr)!)
            // 在swift中，如果要去取得枚举类型的返回值。需要使用raoValue方法
            request!.HTTPMethod = method.rawValue
        } else {
            // POST请求体，是必须要有值的，必须有值提交给服务器
            if let query = queryString(params) {
                request = NSMutableURLRequest(URL: NSURL(string: urlStr)!)
                request!.HTTPMethod = method.rawValue
                request!.HTTPBody = query.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
            }
        }
        
        return request
    }
    
    ///  生成请求参数字符串
    ///
    ///  :param: params 参数字典
    ///
    ///  :returns: 拼接完成的字符串
    func queryString(params: [String: String]?) -> String? {
        // 1.判断参数
        if params == nil {
            return nil
        }
        
        // 2.拼接参数
        // 定义一个数组
        var array = [String]()
        // 遍历字典
        for (k, v) in params! {
            let str = "\(k)=\(v.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!)"
            // 将拼串添加到数组
            array.append(str)
        }
      return (array as NSArray).componentsJoinedByString("&")
//        return join("&", array)
    }
    
    ///  公共的初始化函数
    public init() {}
    
    /// 全局网络回话(可以利用构造函数，设置不同的网络回话设置)
    lazy var session: NSURLSession? = {
        return NSURLSession.sharedSession()
    }()
}